_package("alz.gesture");

_import("alz.util.HashMap");

/**
 * @class AbstractManager
 * @extends Object
 * @ignore
 * Base Manager class - extended by ComponentMgr and PluginMgr
 */
_class("AbstractManager", "", function(){
	this.typeName = 'type';
	this._init = function(config){
		_super._init.call(this);
		config = config || {};
		for(var k in config){
			this[k] = config[k];
		}
		/* *
		 * Contains all of the items currently managed
		 * @property all
		 * @type alz.util.MixedCollection
		 */
		this.all = new HashMap();
		this.types = {};
	};
	this.dispose = function(){
		this.all.dispose();
		this.all = null;
		_super.dispose.apply(this);
	};
	/**
	 * Returns a component by {@link Ext.Component#id id}.
	 * For additional details see {@link alz.util.MixedCollection#get}.
	 * @param {String} id The component {@link Ext.Component#id id}
	 * @return Ext.Component The Component, <code>undefined</code> if not found, or <code>null</code> if a
	 * Class was found.
	 */
	this.get = function(id){
		return this.all.get(id);
	};
	/**
	 * Registers an item to be managed
	 * @param {Mixed} item The item to register
	 */
	this.register = function(item){
		this.all.add(item);
	};
	/**
	 * Unregisters a component by removing it from this manager
	 * @param {Mixed} item The item to unregister
	 */
	this.unregister = function(item){
		this.all.remove(item);
	};
	/**
	 * <p>Registers a new Component constructor, keyed by a new
	 * {@link Ext.Component#xtype}.</p>
	 * <p>Use this method (or its alias {@link Ext#reg Ext.reg}) to register new
	 * subclasses of {@link Ext.Component} so that lazy instantiation may be used when specifying
	 * child Components.
	 * see {@link Ext.Container#items}</p>
	 * @param {String} xtype The mnemonic string by which the Component class may be looked up.
	 * @param {Constructor} cls The new Component class.
	 */
	this.registerType = function(type, cls){
		this.types[type] = cls;
		cls[this.typeName] = type;
	};
	/**
	 * Checks if a Component type is registered.
	 * @param {Ext.Component} xtype The mnemonic string by which the Component class may be looked up
	 * @return {Boolean} Whether the type is registered.
	 */
	this.isRegistered = function(type){
		return type in this.types;
	};
	/**
	 * Creates and returns an instance of whatever this manager manages, based on the supplied type and config object
	 * @param {Object} config The config object
	 * @param {String} defaultType If no type is discovered in the config object, we fall back to this type
	 * @return {Mixed} The instance of whatever this manager is managing
	 */
	this.create1 = function(config, defaultType){
		var type = config[this.typeName] || config.type || defaultType;
		var clazz = this.types[type];
		if(!clazz){
			throw new Error("The '" + type + "' type has not been registered with this manager");
		}
		return new clazz(config);
	};
	/* *
	 * Registers a function that will be called when a Component with the specified id is added to the manager. This will happen on instantiation.
	 * @param {String} id The component {@link Ext.Component#id id}
	 * @param {Function} fn The callback function
	 * @param {Object} scope The scope (<code>this</code> reference) in which the callback is executed. Defaults to the Component.
	 */
	/*
	this.onAvailable = function(id, fn, scope){
		var all = this.all;
		all.on("add", function(index, o){
			if(o.id == id){
				fn.call(scope || o, o);
				all.un("add", fn, scope);
			}
		});
	};
	*/
	/* *
	 * Executes the specified function once for each item in the collection.
	 * Returning false from the function will cease iteration.
	 * 
	 * The paramaters passed to the function are:
	 * <div class="mdetail-params"><ul>
	 * <li><b>key</b> : String<p class="sub-desc">The key of the item</p></li>
	 * <li><b>value</b> : Number<p class="sub-desc">The value of the item</p></li>
	 * <li><b>length</b> : Number<p class="sub-desc">The total number of items in the collection</p></li>
	 * </ul></div>
	 * @param {Object} fn The function to execute.
	 * @param {Object} scope The scope to execute in. Defaults to <tt>this</tt>.
	 */
	/*
	this.each = function(fn, scope){
		this.all.each(fn, scope || this);
	};
	*/
	/* *
	 * Gets the number of items in the collection.
	 * @return {Number} The number of items in the collection.
	 */
	/*
	this.getCount = function(){
		return this.all.getCount();
	};
	*/
});